﻿using Levfier.Proccessors.Parameters;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace Levfier.GUI.EditorControls.Parameters
{
    /// <summary>
    /// ParameterPropertyEditorView.xaml の相互作用ロジック
    /// </summary>
    [Serializable]
    public partial class ParameterPropertyEditorView : UserControl
    {
        /// <summary>
        /// パラメータテーブル
        /// </summary>
        private IDictionary<string, ProccessParameter> parameters;

        /// <summary>
        /// 選択中のパラメータ
        /// </summary>
        private ProccessParameter selectedParameter;

        /// <summary>
        /// 設定対象のコントロール
        /// </summary>
        private ParameterControl control;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="control">設定対象となるパラメータコントロール</param>
        /// <param name="parameters">パラメータテーブル</param>
        public ParameterPropertyEditorView(ParameterControl control, IDictionary<string, ProccessParameter> parameters, ProccessParameter targetParameter)
        {
            InitializeComponent();
            this.parameters = parameters;
            this.control = control;
            this.selectedParameter = targetParameter;

            foreach(ProccessParameter param in parameters.Values)
            {
                //未使用アイテムのみ追加
                if(!param.IsUsed)
                {
                    ComboBoxItem item = new ComboBoxItem();
                    item.Content = param.Name;
                    this.targetParameter.Items.Add(item);

                    if (null != this.selectedParameter)
                    {
                        if (param.Name == this.selectedParameter.Name)
                        {
                            this.targetParameter.SelectedItem = item;
                        }
                        this.InitParameterEditor(this.selectedParameter);
                    }
                }
            }
        }

        /// <summary>
        /// 対象とするパラメータ名が選択された時の動作
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        /// <param name="e">イベント</param>
        private void TargetParameterName_DropDownClosed(object sender, EventArgs e)
        {
            //すでに選択中の場合
            if(null != this.selectedParameter)
            {
                //未使用にする
                this.selectedParameter.IsUsed = false;
            }

            //選択中のコンボボックスを取得する
            ComboBox box = sender as ComboBox;
            ComboBoxItem selectedItem = box.SelectedItem as ComboBoxItem;

            if (null != selectedItem)
            {
                //選択中パラメータとして保持
                this.selectedParameter = this.parameters[selectedItem.Content.ToString()];
                this.control.TargetParameter = this.selectedParameter;
                this.selectedParameter.IsUsed = true;

                //初期表示を行う
                this.InitParameterEditor(this.selectedParameter);

                //イベントハンドラ登録
                this.minValue.ValueChanged += this.MinValueSlider_ValueChanged;
                this.maxValue.ValueChanged += this.MaxValueSlider_ValueChanged;
                this.currentValue.ValueChanged += this.CurrentValueSlider_ValueChanged;
            }
        }

        /// <summary>
        /// 現在値が変更された時の動作
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        /// <param name="e">イベント</param>
        private void CurrentValueSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            ParameterSlider slider = sender as ParameterSlider;
            double current = slider.parameterSlider.Value;

            //現在値・最大値スライダの最小値を変更する
            this.selectedParameter.Value = current;
        }

        /// <summary>
        /// 最大値を設定するスライダが変更された時の動作
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        /// <param name="e">イベント</param>
        private void MaxValueSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            ParameterSlider slider = sender as ParameterSlider;
            double max = slider.parameterSlider.Value;

            //現在値・最大値スライダの最小値を変更する
            this.currentValue.parameterSlider.Maximum = max;
            this.minValue.parameterSlider.Maximum = max;
            this.control.MaxValue = max;
        }

        /// <summary>
        /// 最小値を設定するスライダが変更された時の動作
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        /// <param name="e">イベント</param>
        private void MinValueSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            ParameterSlider slider = sender as ParameterSlider;
            double min = slider.parameterSlider.Value;

            //現在値・最大値スライダの最小値を変更する
            this.currentValue.parameterSlider.Minimum = min;
            this.maxValue.parameterSlider.Minimum = min;
            this.control.MinValue = min;
        }

        /// <summary>
        /// 対象パラメータを画面に初期表示する
        /// </summary>
        /// <param name="parameter">表示対象パラメータ</param>
        private void InitParameterEditor(ProccessParameter parameter)
        {
            //最大値スライダ
            this.maxValue.parameterSlider.Maximum = parameter.MaxValue;
            this.maxValue.parameterSlider.Minimum = parameter.MinValue;
            this.maxValue.parameterSlider.Value = parameter.MaxValue;
            this.maxValue.parameterName.Text = "Max";
            
            //最小値スライダ
            this.minValue.parameterSlider.Maximum = parameter.MaxValue;
            this.minValue.parameterSlider.Minimum = parameter.MinValue;
            this.minValue.parameterSlider.Value = parameter.MinValue;
            this.minValue.parameterName.Text = "Min";

            //現在値スライダ
            this.currentValue.parameterSlider.Maximum = parameter.MaxValue;
            this.currentValue.parameterSlider.Minimum = parameter.MinValue;
            this.currentValue.parameterSlider.Value = parameter.Value;
            this.currentValue.parameterName.Text = "Current";
        }
    }
}
